package com.qf.fmall.utils;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class WxpayUtils {

    // 微信支付统一下单接口url
    public static final String UNIFY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    // 微信支付查询订单状态接口的url
    public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

    public static final String APPID = "wx632c8f211f8122c6";

    public static final String MCH_ID = "1497984412";

    public static final String SECRET_KEY = "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";


    /**
     * 根据订单编号查询订单状态
     * @param orderid
     * @return 返回订单状态字符串
     */
    public static String queryOrder(String orderid){

        // 把hashmap转换为 xml字符串
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("appid",APPID);
        hashMap.put("mch_id",MCH_ID);
        String nonce_str = UUID.randomUUID().toString().replaceAll("-","");
        System.out.println(nonce_str);
        hashMap.put("nonce_str",nonce_str);
        hashMap.put("out_trade_no",orderid); // 订单编号

        // 计算签名，把签名信息放入请求参数中
        String sign =  createSign(hashMap);

        // 签名
        hashMap.put("sign",sign);

        String s = XmlUtil.mapToXmlStr(hashMap);
        log.info("请求微信查询接口的参数为，xml={}",s);

        // 调用微信支付
        String body = HttpRequest.post(QUERY_ORDER_URL)
                .body(s)
                .execute()
                .body();

        log.info("微信查询接口返回的xml为，{}",body);
        // xml转换 map
        Map<String, Object> map = XmlUtil.xmlToMap(body);
        return (String) map.get("trade_state");

    }


    /**
     * 调用微信支付平台，获取payurl
     * @param orderid 订单编号
     * @param content 订单内容
     * @param amount 订单金额,单位分
     * @return
     */
    public static String getPayurl(String orderid,String content,Integer amount){

        // 把hashmap转换为 xml字符串
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("appid",APPID);
        hashMap.put("mch_id",MCH_ID);
        String nonce_str = UUID.randomUUID().toString().replaceAll("-","");
        System.out.println(nonce_str);
        hashMap.put("nonce_str",nonce_str);
        hashMap.put("body",content);
        hashMap.put("out_trade_no",orderid); // 订单编号
        hashMap.put("total_fee","1");  // 1分钱
        hashMap.put("notify_url","http://47.118.45.73:8080/pay/callback");
        hashMap.put("trade_type","NATIVE");

        // 计算签名，把签名信息放入请求参数中
        String sign =  createSign(hashMap);

        // 签名
        hashMap.put("sign",sign);

        String s = XmlUtil.mapToXmlStr(hashMap);

        // 调用微信支付
        String body = HttpRequest.post(UNIFY_ORDER_URL)
                .body(s)
                .execute()
                .body();

        System.out.println(body);
        // xml转换 map
        Map<String, Object> map = XmlUtil.xmlToMap(body);

        String payurl = (String) map.get("code_url");
        System.out.println(payurl);
        return payurl;
    }

    private static String createSign(HashMap<String, String> hashMap) {

        //1. 对map中的key进行升序排序
        Set<String> keySet = hashMap.keySet();

        //2. 对set中的key进行升序排序
        TreeSet<String> set = new TreeSet<>(keySet);

        //3. stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";

        StringBuffer stringBuffer = new StringBuffer();
        for (String key : set) {

            // 如果key对应的value为空，那么这个key不要参与签名的计算
            if (hashMap.get(key)==null|| hashMap.get(key).equals("")){
                continue;
            }

            String value = hashMap.get(key);
            stringBuffer.append(key);
            stringBuffer.append("=");
            stringBuffer.append(value);
            stringBuffer.append("&");
        }
        String stringA = stringBuffer.toString();
        log.info("签名的字符串为,stringA={}",stringA);
        String stringSignTemp=stringA+"key="+SECRET_KEY; //注：key为商户平台设置的密钥key
        String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase();
        return sign;
    }

}
